package nl.rug.ai.believer.model;

/**
 * This class represents a relation between 2 worlds. Each relation is owned by an agent.
 * 
 * @author S1849700
 *
 */
public class Relation {
	
	private Agent agent;
	private World from;
	private World to;

	/**
	 * Standard constructor, used to initialize the agent, the from world and the to world of this relation.
	 * @param agent the agent to who this relation belongs
	 * @param from the from world from which this relation originates.
	 * @param to the to world, to where this relation goes. (In case of refelxive relations, identical to from.
	 */
	public Relation(Agent agent, World from, World to) {
		if (agent == null || from == null || to == null) {
			throw new NullPointerException("Contructor element of Relation was null.");
		}
		this.agent = agent;
		this.from = from;
		this.to = to;
	}
	
	/**
	 * accessor method for the agent of this relation
	 * @return the agent.
	 */
	public Agent getAgent() {
		return agent;
	}
	
	/**
	 * accessor method for the to world
	 * @return the to world
	 */
	public World getToWorld() {
		return to;
	}

	/**
	 * accessor method for the from world
	 * @return the from world
	 */
	public World getFromWorld() {
		return from;
	}

	/**
	 * We consider an Agent equal if their name is equal.
	 * @see Object#equals(Object)
	 */
	@Override 
	public boolean equals(Object other) {
	    //check for self-comparison
	    if ( this == other ) {
	    	return true;
	    }
	    // this renders an explicit check for "other == null" redundant, since it does the check for 
	    // null already - "null instanceof [type]" always returns false. 
	    if (!(other instanceof Relation)) {
	    	return false;
	    }
	    Relation otherRelation = (Relation)other;
	    // if agent, from and to worlds are equal, the relation is equal.
	    return otherRelation.agent.equals(agent) && otherRelation.from.equals(from) && otherRelation.to.equals(to);
	}
	
	/**
	 * @see Object#hashCode(Object)
	 */
	// must be overwritten if .equals is overwritten. (And should be based on the same key fields.)
	@Override 
	public int hashCode() {
		return (agent.hashCode() * 31 + from.hashCode()) * 31 + to.hashCode();
	}

}
